package client;




import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

import java.util.ArrayList;



class NavireCompartiment implements NavireConst, NavireConstGraph
{	/** position du bateau */
	int lig;
	/** position du bateau */
	int col;
	/** etat de la case Rien ou Touche */ 
	int etat;
	
	public NavireCompartiment()
	{ 	this.etat=Intact; this.lig=-1; this.col=-1;		}
	
	/**
	 * @param lig position de la case
	 * @param col position de la case
	 */
	public void init(int lig, int col)
	{	this.etat=Intact; this.lig=lig; this.col=col;	}
	
	/** test le tir il y a une option à prendre si la case est déjà touchée
	 * @param lig position de la case
	 * @param col position de la case
	 * @return Rate ou Touche ou EnVue
	 */
	public int tir2(int lig, int col)
	{	int renvoi =Rate;
		if((this.col==col)&& (this.lig==lig)) 
		{	if (etat==Touche) renvoi=EnVue;
			else {	etat=Touche; renvoi=etat;		}
		}
		else if((Math.abs(col-this.col)<=1)&& (Math.abs(this.lig-lig)<=1)) 
			renvoi=EnVue; 
		return renvoi;
	}
	
	public String toString()
	{	return "lig="+lig+" col="+col+" état "+mess[etat]; }
	
	
	public void afficher(Graphics g)
	{	//System.out.println("lig="+lig+"  col="+col);
		Point pt = ChaineClientFrame.quelPoint(col, lig);
		if(etat==Touche) g.setColor(Color.red); else g.setColor(Color.blue);
		g.fillRect(pt.x, pt.y, Cote, Cote);
		
	}
}

abstract class Navire implements NavireConst
{		
	/** cases du bateau dans la grille */
	private NavireCompartiment lcase[] ;
	/** etat du bateau Rien ou Touche ou Coule */
	private int etat;
	/** utilisé par tir2    */
	private int nbtouche;
	/**
	 * création des tableaux 
	 * @param nbcases nombre de cases du bateau
	 */
	public Navire(int nbcases)
	{	lcase= new NavireCompartiment[nbcases];
		for(int i=0; i<lcase.length; i++) lcase[i]=new NavireCompartiment();
		init();
	}
	/** tirage au sort de la position des bateaux */
	public void init()
	{	Point pt[] =tirage(lcase.length);
		for(int i=0; i<pt.length; i++) lcase[i].init(pt[i].y,pt[i].x);
		etat = Intact;
		nbtouche= lcase.length;  // pour tir2
	}
	
	public static Point[]  tirage(int nb)
	{	Point  deux [] = {new Point(1,1),new Point(1,2)};
		Point trois [] = {new Point(4,1),new Point(4,2),new Point(4,3)};
		if (nb==2) return deux; else return trois;
	}
	/** 
	 * @param pt position de la case
	 * @return Rate ou Touche ou EnVue ou Coule
	 */
	public int tir2(int lig, int col)
	{	int res=Rate;
		System.out.println( " tir2 "+etat+ mess[etat]);
		if (etat!=Coule)
		{	for(int i=0; i<lcase.length&&res!=Touche&&res!=Coule; i++)
			{	res = Math.max(res, lcase[i].tir2(lig, col));		
				if (res==Touche)
				{	nbtouche--;	etat=Touche;
					if(nbtouche==0) {	etat=Coule; res=Coule;    }
				}
			}
		}
		//System.out.println( " tir2 "+etat+ mess[etat]+res+mess[res]);
		return res;
	}
		
	public String toString()
	{	String str = " état "+mess[etat];
		for(int i=0; i<lcase.length; i++) str = str+ lcase[i].toString();		
		return str;
	}
	public void afficher(Graphics g)
	{	//System.out.println("navire "+lcase.length);
		for(int i=0; i<lcase.length; i++) lcase[i].afficher(g);
	}
		
}

class NavireTorpilleur extends Navire
{	/** un torpilleur est sur deux cases */
	private static final int NbCase =2;
	private static final String nom = "Torpilleur";

	public NavireTorpilleur()	{	super(NbCase);		}
	
	public String toString(){		return nom+" "+super.toString();	}	
}

class NavireCroiseur extends Navire
{	/** un croiseur est sur trois cases */
	private static final int NbCase =3;
	private static final String nom = "Croiseur";

	public NavireCroiseur()	{	super(NbCase);		}
	
	public String toString()	{	return nom+" "+super.toString();	}
}

class NavireRepTir
{
	public int lig;
	public int col; 
	public int rep;
	
	public NavireRepTir(int lig, int col,  int rep)
	{
		this.lig = lig; this.col = col; this.rep = rep;
	}
}

public class NavireJoueur implements NavireConst , NavireConstGraph
{	/** identité du joueur 0 ou 1 */
	private int ident;
	/** liste des bateaux */
	private ArrayList<Navire> bat;
	/** nombre de bateaux coulés */
	int nbcoule;
	/** liste des tir */
	private ArrayList<NavireRepTir> mestirs;
	
	/**
	 */
	public NavireJoueur()
	{ 	ident = 99999;
		bat = new ArrayList<Navire> ();	
		bat.add(new NavireTorpilleur());	bat.add(new NavireCroiseur());
		mestirs = new ArrayList<NavireRepTir>();
	}
	/** tirage au sort de la position des bateaux */
	public void init()
	{	bat.add(new NavireTorpilleur());	bat.add(new NavireCroiseur());
		for (int i=0; i<bat.size(); i++) bat.get(i).init();	
		nbcoule = bat.size();
	}
	/** 
	 * @param pt position de la case
	 * @return Rate ou Touche ou EnVue ou Coule ou Gagne
	 */
	int tir(int lig, int col)
	{	int resul = Rate;
		int res= Rate;
		
		for(int i=0;  i<bat.size()&&res!=Touche&&res!=Coule&&res!=Gagne; i++)
		{	res = bat.get(i).tir2(lig, col);
			resul = Math.max(res, resul);
			if(res==Coule )	{	nbcoule--;  if(nbcoule==0) resul =Gagne;	}		
		}
		return resul;
	}
	public String toString()
	{	String str = " joueur "+ident+"\n";
		for(int i=0; i<bat.size(); i++) str = str+ bat.get(i).toString()+"\n";		
		return str;
	}
	
	public void afficher(Graphics g)
	{	//System.out.println(bat.size());
		for(int i=0; i<bat.size(); i++) bat.get(i).afficher(g);	
		for(int i=0; i<mestirs.size(); i++)
		{	NavireRepTir tir = mestirs.get(i);
			Point pt = ChaineClientFrame.quelPoint(tir.col, tir.lig);
			switch( tir.rep)
			{ 	case Rate : g.setColor(Color.blue); break;
				case EnVue : g.setColor(Color.green); break;
				case Touche : g.setColor(Color.red); break;
				default : g.setColor(Color.black); 
			}
			g.fillRect(pt.x+DxTir+ 2*Dxy, pt.y, Cote, Cote);
			
		}
	}
	  
	/**
	 * @param lig  ligne du tir
	 * @param col  colonne du tir
	 * @return la valeur caractère de la réponse 
	 */
	public String recoitTir(int lig, int col)
	{	//System.out.println("recoitTir");
		return mess[tir(lig, col)];
	}
	/**
	 * 
	 * @param lig  ligne du tir
	 * @param col  colonne du tir
	 * @param rep  la valeur caractère de la réponse 
	 */
	public void recoitReponseTir(int lig, int col, String rep)
	{	int i;
		for (i=0; i<mess.length && !mess[i].equals(rep); i++);
		NavireRepTir tir = new NavireRepTir(lig, col, i);
		this.mestirs.add(tir);	
	}
}






